/**
 * 注：
 * videoId就是swiper-item的索引
 */
// 方向枚举常量
const DIRECTION = {
  UP: 'UP',
  DOWN: 'DOWN'
};
// 当前时间戳
let curT,
//上次旧的时间戳
prevT,
// 是的执行了单击tap事件
isExecTap,
// 停止单击的定时器interval
tapInterval,
// 开始Y位置
startTouchY,
// 结束Y位置
endTouchY,
// 是否执行了
isExecAni,
// 循环次数
cycleCount = 1;
Component({
  options: {
    multipleSlots: true
  },
  properties: {
    // 是否是满屏播放
    isFullScreen: {
      type: Boolean,
      value: false
    },
    bottomBarHeight: {
      type: Number,
      optionalTypes: [Boolean],
      value: 0
    },
    // 是否有圆角
    isHasRaduis:{
      type: Boolean,
      value: true
    },
    // 是否显示进度条
    isShowProgressBar:{
      type: Boolean,
      value: true
    },
    // 是否允许重播
    isAllowReplay:{
      type: Boolean,
      value: true
    },
    // 播放的视频列表, 
    dataList:{ 
      type: Array,
      value: []
    }
  },
  data: {
    // 已观看的历史栈
    watchedStack: [], 
    // 记录栈顶位置
    watchedPos: -1,
    // 全部播放队列
    allQueue: [],
    // 存放dataList
    groupQueue: [],
    // 当前组大小
    groupSize: 12,
    // 组号（组页）
    groupNum: 1,
    // 组数量
    groupCount: 0,
    // 当前播放队列
    curQueue: [],
    // 当前swiper-item，在组中的页号
    curQueueNum: 1,
    // 当前页大小
    curQueueSize: 3,
    // 当前播放索引
    curIndex: 0,
    // 是否循环swiper
    circular: false,
    // 过渡时长
    duration: 360,
    // 是否自动播放视频
    autoplay: false,
    // 是否在播放/暂停状态 true: 播放，false：暂停
    playStaus: true,
    // 加载完成的视频id（视频索引）
    loadedVideoIds: [],
    // 滑块颜色
    blockColor: 'transparent',
    // 是否允许更新slider进度
    isUpProgess: true,
    // 状态栏高度
    topStatusHeight: 0,
    // 底部状态栏高度
    bottomStatusBarHeight: 0,
    subEvents: [],
    // 判断是否是Boolean类型值的函数
    isBoolean: null,
    // 是否布局完成
    isLayoutEnd: false,
    // 滑动方法
    direction: ''
  },

  observers:{
    // dataList(val){
    //   if(!this.exist(this.data.allQueue) && !this.exist(val)){ return }
    //   this.initPlayQueue(this.data.groupVideo)
    // }
    isLayoutEnd(val){
      if(val){

      }
    }
  },

  lifetimes: {
    attached() {
      this.setData({
        isBoolean: this.isType('boolean')
      })
      this.initPlayQueue(this.data.dataList)
    },
    ready() {
      const { topStatusBsrHeight, bottomStatusBarHeight } = this.getNavbar();
      this.setData({
        topStatusBsrHeight,
        bottomStatusBarHeight
      });
      this.data.isBoolean(this.data.bottomBarHeight) && this.setData({
        bottomBarHeight: bottomStatusBarHeight
      })
      this.setData({
        isLayoutEnd: true
      })
    }
  },

  methods: {
    getNavbar() {
      const { statusBarHeight, safeArea, screenHeight } = wx.getSystemInfoSync();
      //胶囊按钮
      const capsule = wx.getMenuButtonBoundingClientRect();
      const areaHeight = capsule && capsule.bottom + capsule.top - statusBarHeight + 4 || statusBarHeight + 46;
      return { 
        areaHeight,
        screenHeight,
        topStatusBsrHeight: statusBarHeight,
        bottomStatusBarHeight: screenHeight - safeArea.bottom
      };
    },
    exist(data){
      let flag = true;
      //存在的是有意义的
      flag = !!data;
      //小于等于0的数，认为是不存在的
      isFinite(data) && data <= 0 && (flag = false);
      //空对象
      JSON.stringify(data) === '{}' && (flag = false);
      //空数组
      Array.isArray(data) && data.length == 0 && (flag = false);
      return flag;
    },
    isType(type){
      type = type.charAt(0).toUpperCase()+type.substring(1);
      return function(obj){
        return Object.prototype.toString.call(obj) == `[object ${type}]`;
      }
    },
    // 初始化播放队列
    initPlayQueue(videos, start = 0) {
      //this.data.allQueue.push.apply(this.data.allQueue,videos);
      this.data.allQueue.push(...videos);
      const curQueue = videos.slice(start, this.data.curQueueSize);
      this.setData({
        allQueue: this.data.allQueue,
        groupQueue: videos,
        groupCount: videos.length,
        curQueue,
        curQueueSize: curQueue.length
      })
    },
    swiperTouchStart(e){
      startTouchY = e.changedTouches[0].clientY;
    },
    swiperTouchEnd(e) {
      endTouchY = e.changedTouches[0].clientY;
      this.setData({
        direction: startTouchY - endTouchY > 0 ? DIRECTION.UP : DIRECTION.DOWN
      })
      this.$emit('swiperTouchEnd', this.data.direction)
    },
    swiperChange(e) {
      this.$on('swiperTouchEnd', direction => {
        const { current: curIndex } = e.detail;
        if(this.data.curIndex == curIndex){return}
        isExecAni = false;
        // 停止所有视频播放
        this.stopAllPlay();
        // 更新当前索引
        this.setData({ 
          curIndex, 
          playStaus: true, 
          progressBarValue: 0
        });
        // 根据方向，对视频出入栈
        if(direction == DIRECTION.UP) { // 入栈
          if(curIndex == 0){
            this.setData({
              curQueueNum: (this.data.curQueueNum+1) % (this.data.groupSize / this.data.curQueueSize)
            })
          }
          // 当入栈数量小于可入栈数量时，才允许下一个入栈。可入栈数量（总数量 - 1)
          if(this.data.watchedPos+1 < this.data.groupCount-1){
            //获取每组中，需要入栈的索引
            const stackIndex = this.data.watchedPos+1 % this.data.groupSize;
            this.pushStack(this.data.groupQueue[stackIndex]);
            // 设置下一个swiperItem数据
            this.setNextSwiperItem(curIndex);
          }
        } else { // 出栈
          if(curIndex == this.data.curQueueSize - 1){
            this.setData({
              curQueueNum: this.data.curQueueNum - 1 || 1
            })
          }
          // 设置前一个swiperItem数据
          this.setPrevSwiperItem(curIndex);
          this.popStack();
        }
        console.log(this.data.curQueueNum)
        // swiperAnimated挽救器
        this.swiperAnimatedRescuer(e);
        //this.triggerEvent('swiperChange', {curIndex, video: this.data.curQueue[curIndex] })
      },true);
    },
    swiperAnimated(e) {
      isExecAni = true;
      this.setCircular();
      // 播放curIndex视频
      const curIndex = e.detail.current;
      //如果在播放状态，则停止所有视频后，播放当前视频
      if(this.data.playStaus){
        this.stopAllPlay().setVideoPlay(curIndex);
      }
    },
    // swiperAnimated挽救器
    swiperAnimatedRescuer(e) {
      setTimeout(()=> {
        !isExecAni && this.swiperAnimated(e)
      }, this.data.duration+10);
    },
    // 设置swiper循环条件
    setCircular() {
      if(this.data.allQueue.length <= this.data.curQueueSize){return}
      // 栈内有数据，并且栈内数据小于总的可入栈数（可入栈数 = 总数量 - 1）
      const circular = this.data.watchedPos > -1 && this.data.watchedPos+1 < this.data.allQueue.length-1
      if(circular == this.data.circular){return}
      this.setData({
        circular
      })
    },
    // 视频加载完成事件
    videoLoaded(e){
      const duration = e.detail.duration;
      const videoId = e.currentTarget.id;
      //首次进入，自动播放第一个视频
      videoId == '0' && this.autoPlayFirstVideo()
      // 保存当前视频的播放时长
      !this.data.curQueue[videoId].hasOwnProperty('duration')
      &&
      this.setData({
        [`curQueue[${videoId}].duration`]: duration
      });
      // !this.data.loadedVideoIds.includes(String(videoId)) && this.data.loadedVideoIds.push({
      //   video: this.data.curQueue[videoId],
      //   videoId,
      //   duration
      // });
      // if(this.data.loadedVideoIds.length == this.data.swiperSize){
      //   this.triggerEvent('allVideoLoaded', [this.data.loadedVideoIds]);
      // }
    },
    videoPlay(e){
      let videoId = e.currentTarget.id;
      // 当前视频播放结束事件
      if(videoId == this.data.curIndex) {
        this.triggerEvent('curVideoEnd', {
          curIndex: videoId,
          videoId,
          video: this.data.curQueue[videoId]
        })
      }
    },
    // 播放结束事件
    videoEnd(e) {
      let videoId = e.currentTarget.id;
      // 允许重播, 才重播
      if(this.data.isAllowReplay){
        this.setVideoPlay(e.currentTarget.id);
        this.setData({
          progressBarValue: 0
        })
      }else{
        this.setData({
          playStaus: false
        })
      }
      // 当前视频播放结束事件
      if(videoId == this.data.curIndex) {
        this.triggerEvent('curVideoEnd', {
          curIndex: videoId,
          videoId,
          video: this.data.curQueue[videoId]
        })
      }
    },
    // 点击视频的tap事件
    onVideoTap(e){
      curT = new Date().getTime();
      !prevT && (prevT = curT)
      // 双击事件
      if(curT - prevT <= 300 && curT - prevT > 0){
        //双击事件
        this.videoDouble(e)
        if(isExecTap){
          // console.log('停止了，单击事件')
          // 停止单击事件，重置为未执行状态
          isExecTap = false
          clearTimeout(tapInterval);
        }
      }else{
        //是否执行了点击事件
        isExecTap = true;
        tapInterval = setTimeout(()=> {
          // console.log('执行单击tap事件');
          this.videoTap(e)
        },300);
      }
      prevT = curT;
    },
    // 视频双击事件
    videoDouble(e){
      this.triggerEvent('videoDouble', {
        e,
        video: this.data.curQueue[e.currentTarget.id]
      })
    },
    // 视频单击事件
    videoTap(e) {
      let videoId = e.currentTarget.id;
      this.togglePlay(videoId)
    },
    // 暂停/播放事件
    togglePlay(videoId) {
      this.data.playStaus ? this.setVideoPause(videoId) : this.setVideoPlay(videoId);
      this.setData({
        playStaus: !this.data.playStaus
      })
      this.triggerEvent('videoPlayStaus', this.data.playStaus)
    },
    // 视频加载异常事件
    videoError() {
      wx.showToast({
        title: '网络不给力！为了您更好的体验，请检查您的网络哦~',
        duration: 2500,
        icon: 'none'
      });
    },
    // 视频时间戳改变事件 
    videoTimeUpdate(e) {
      // 只在允许更新进度时，才能更新
      this.data.isUpProgess && this.setData({
        progressBarValue: e.detail.currentTime / e.detail.duration * 100
      })
    },
    // 进度条change事件
    progressChange(e) {
      const value = e.detail.value;
      const videoId = e.currentTarget.id;
      const video = this.data.curQueue[videoId]
      wx.createVideoContext(String(videoId), this).seek(value / 100 * video.duration);
      this.setData({
        blockColor: 'transparent',
        progressBarValue: value,
        isUpProgess: true // 进度改变后，才允许更新
      })
    },
    // 进度条拖拽中的事件
    progressChanging(e) {
      this.setData({
        blockColor: '#FFFFFF',
        isUpProgess: false // 拖拽过程中，不允许更新进度
      })
    },
    pushStack(item) {
      const watchedStack = this.data.watchedStack;
      if(!watchedStack.includes(item)) {
        watchedStack.push(item);
        this.setData({
          watchedStack: this.data.watchedStack,
          watchedPos: this.data.watchedPos+1
        })
      }
    },
    // 移除栈顶元素
    popStack() {
      const watchedStack = this.data.watchedStack;
      const item = watchedStack.pop();
      this.setData({
        watchedStack: watchedStack,
        watchedPos: watchedStack.length-1
      })
      return item;
    },
    // 设置下一个swiperItem数据
    setNextSwiperItem(curIndex){
      // 入栈数大于等于2(swiperSize-1)
      if(this.data.watchedPos+1 >= this.data.curQueueSize-1){
        const nextIndex = this.getNextIndex(curIndex);
        this.setData({
          [`curQueue[${nextIndex}]`]: this.data.allQueue[this.data.watchedPos+2]
        })
        this.triggerEvent('up-swiper-item', { slotItem: this.data.curQueue[nextIndex], curQueue: this.data.curQueue, videoQueue: this.data.videoQueue, curIndex: nextIndex })
      }
    },
    // 设置前一个swiperItem数据
    setPrevSwiperItem(curIndex){
      // 如果栈内有数据
      if(this.data.watchedPos > -1){
        const prevIndex = this.getPrevIndex(curIndex);
        this.setData({
          [`curQueue[${prevIndex}]`]: this.data.watchedStack[this.data.watchedPos-1]
        })
        this.triggerEvent('up-swiper-item', { slotItem: this.data.curQueue[prevIndex], curQueue: this.data.curQueue, videoQueue: this.data.videoQueue, curIndex: prevIndex })
      }
    },
    getNextIndex(curIndex) {
      return (curIndex+1)%this.data.curQueueSize;
    },
    getPrevIndex(curIndex){
      return curIndex ? curIndex-1 : this.data.curQueueSize-1;
    },
    autoPlayFirstVideo(){
      this.data.watchedPos < 0 && this.setVideoPlay(0)
    },
    setVideoPlay(videoId) {
      wx.createVideoContext(String(videoId), this).play();
    },
    setVideoPause(videoId) {
      wx.createVideoContext(String(videoId), this).pause();
    },
    stopAllPlay(){
      const allIndex = Array.from({ length: this.data.swiperSize }, (v, i) => i);
      allIndex.forEach(curIndex => this.setVideoPause(curIndex))
      return this;
    },
    $emit(event,data){
      const subEvent = this.data.subEvents[event];
      subEvent && subEvent.forEach(handle => handle.call(this, data));
    },
    $on(event,handle,onlyOne){
      let subEvents = this.data.subEvents;
      (!(event in subEvents) || onlyOne) && (subEvents[event] = [])
      subEvents[event].push(handle);
    },
    $off(event,handle){
      let subEvent = this.data.subEvents[event];
      if(!handle){
        subEvent && delete this.data.subEvents[event]
      }else{
        if(typeof handle == 'function' && subEvent){
          subEvent.forEach((event,i) => {
            event == handle && subEvent.splice(i,1)
          });
        }
      }
    },
    getCurVideoDuration() {
      return this.data.curQueue[this.data.watchedPos+1].duration
    },
    // 获取[每组]入栈数
    getGroupStackCount(){
      return this.watchedPos+1%this.data.swiperSize;
    }
  }
})
